﻿
using SimpleInjector;
using SimpleInjector.Extensions.ExecutionContextScoping;
using Sustainalytics.ClientDW.Entities;
using Sustainalytics.Companies;
using Sustainalytics.DataLayer;
using Sustainalytics.DataLayer.ConnectionStrings;
using Sustainalytics.DataLayer.Shared;
using Sustainalytics.Entities;
using Sustainalytics.Entities.ConnectionStrings;
using Sustainalytics.OAuth.Services.Common;
using Sustainalytics.Portfolios.BL;
using Sustainalytics.Portfolios.Service.Controllers;
using Sustainalytics.Portfolios.Service.Models;
using Sustainalytics.Portfolios.Service.Utility;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Dispatcher;

namespace Sustainalytics.Portfolios.Service.Infrastructure
{

    public class CompositionRoot : IHttpControllerActivator
    {
        public IHttpController Create(
            HttpRequestMessage request,
            HttpControllerDescriptor controllerDescriptor,
            Type controllerType)
        {
            var clientPlatform = ConfigurationManager.ConnectionStrings["ClientPlatform"].ConnectionString;
            var esgInputFileRepository = EsgInputFileRepository.GetInstance(new FileRepository(clientPlatform), new RepositoryCollection<EsgInputFile>(clientPlatform));


            var serviceBusParams = new Dictionary<string, string>
                {
                        { "ConnectionString", ConfigurationManager.AppSettings["Microsoft.ServiceBus.ConnectionString"] },
                        { "RegionEndpoint", ConfigurationManager.AppSettings["Microsoft.ServiceBus.RegionEndpoint"] },
                        { "SessionId", ConfigurationManager.AppSettings["Microsoft.ServiceBus.SessionId"] },
                        { "TopicPath", ConfigurationManager.AppSettings["Microsoft.ServiceBus.TopicPath"] },
                };

            var connectionStringsManager =
                ConnectionStringsManager.GetInstance(
                    ConnectionStringsRepository.GetInstance(clientPlatform));

            var portfolioReader = new PortfolioReadHandler(
                new RepositoryCollection<CorporateDataBasic>(
                    connectionStringsManager.GetConnectionString(ConnectionStringType.ClientDW),
                    "CorporateData"));

            var subscriptionManager = SubscribeToPortfolioManagement.GetInstance(new SubscribeToPortfolioRepository(clientPlatform), serviceBusParams);

            var portfolioDtoCreator = new PortfolioDtoCreator(subscriptionManager);

            if (controllerType == typeof(PortfoliosController))
            {
                var portfolioUpdateHandler =
              new CustomPortfolioUpdateHandler(
                  new RepositoryCollection<Portfolio>(clientPlatform),
                  new RepositoryCollection<PortfolioDetails>(clientPlatform),
                  new RepositoryCollection<PortfolioMatches>(clientPlatform),
                  new RepositoryCollection<PortfolioUserInput>(clientPlatform),
                  serviceBusParams);

                var portfolioScreeningTollFilteManagement =
             new ScreeningToolFilterManager(new RepositoryCollection<Filter>(clientPlatform));
                portfolioUpdateHandler.SetScreeningToolFilterManagement(portfolioScreeningTollFilteManagement);
                portfolioUpdateHandler.SetSubscriptionManager(subscriptionManager);
                portfolioUpdateHandler.SetPortfolioMatching(new PortfolioMatching(CompanySearchLogic.GetInstance(), new CorporateDataUniversesLoader(MongoDB.Extensions.MongoFactory.GetCollectionFromDatabase<CorporateData>(connectionStringsManager.GetConnectionString(ConnectionStringType.ClientDW)))));

                return new PortfoliosController(
                    portfolioReader,
                    portfolioDtoCreator,
                    portfolioUpdateHandler,
                    new PortfolioRenameHandler(
                        new RepositoryCollection<Portfolio>(clientPlatform),
                        new RepositoryCollection<Portfolio>(
                            connectionStringsManager.GetConnectionString(ConnectionStringType.ClientDW)),
                            serviceBusParams),
                    new PortfolioDeleteHandler(
                       new PortfolioType(
                        new PortfolioMongoCollections(new RepositoryCollection<Portfolio>(clientPlatform),
                        new RepositoryCollection<PortfolioDetails>(clientPlatform),
                        new RepositoryCollection<PortfolioUserInput>(clientPlatform)),

                        new PortfolioMongoCollections(
                        new RepositoryCollection<Portfolio>(connectionStringsManager.GetConnectionString(ConnectionStringType.ClientDW)),
                        new RepositoryCollection<PortfolioDetails>(connectionStringsManager.GetConnectionString(ConnectionStringType.ClientDW)),
                        new RepositoryCollection<PortfolioUserInput>(connectionStringsManager.GetConnectionString(ConnectionStringType.ClientDW)))),
                        portfolioScreeningTollFilteManagement,
                        subscriptionManager,
                        serviceBusParams)
                        , new PortfolioUserClaimsProcessor());
            }

            if (controllerType == typeof(SystemPortfolioController))
            {
                var portfolioScreeningTollFilteManagement =
             new ScreeningToolFilterManager(new RepositoryCollection<Filter>(clientPlatform));
                return new SystemPortfolioController(
                    portfolioReader,
                    new SystemPortfolioDtoCreator(),
                    new ManualSystemPortfolioUpdatesHandler(
                        new RepositoryCollection<Portfolio>(connectionStringsManager.GetConnectionString(ConnectionStringType.ClientDW)),
                        portfolioScreeningTollFilteManagement,
                        subscriptionManager,
                        serviceBusParams), new PortfolioUserClaimsProcessor());
            }

            if (controllerType == typeof(PortfolioMatchedSecuritiesExportController))
            {
                var portfolioUpdateHandler = new CustomPortfolioUpdateHandler(
                    new RepositoryCollection<Portfolio>(clientPlatform),
                    new RepositoryCollection<PortfolioDetails>(clientPlatform),
                    new RepositoryCollection<PortfolioMatches>(clientPlatform),
                    new RepositoryCollection<PortfolioUserInput>(clientPlatform),
                    serviceBusParams);

                var portfolioSecurityManager = new PortfolioSecuritiesImportManagement(
                    esgInputFileRepository,
                    new RepositoryCollection<Portfolio>(clientPlatform),
                    portfolioUpdateHandler,
                    new PortfolioWorksheetValidator());

                return new PortfolioMatchedSecuritiesExportController(portfolioSecurityManager);
            }

            if (controllerType == typeof(PortfoliosDetailsController))
            {
                var portfolioUpdateHandler =
              new CustomPortfolioUpdateHandler(
                  new RepositoryCollection<Portfolio>(clientPlatform),
                  new RepositoryCollection<PortfolioDetails>(clientPlatform),
                  new RepositoryCollection<PortfolioMatches>(clientPlatform),
                  new RepositoryCollection<PortfolioUserInput>(clientPlatform),
                  serviceBusParams);
                var portfolioScreeningTollFilteManagement =
             new ScreeningToolFilterManager(new RepositoryCollection<Filter>(clientPlatform));
                portfolioUpdateHandler.SetScreeningToolFilterManagement(portfolioScreeningTollFilteManagement);
                portfolioUpdateHandler.SetSubscriptionManager(subscriptionManager);
                portfolioUpdateHandler.SetPortfolioMatching(new PortfolioMatching(CompanySearchLogic.GetInstance(), new CorporateDataUniversesLoader(MongoDB.Extensions.MongoFactory.GetCollectionFromDatabase<CorporateData>(connectionStringsManager.GetConnectionString(ConnectionStringType.ClientDW)))));

                return new PortfoliosDetailsController(
                    portfolioReader,
                    portfolioUpdateHandler, new PortfolioUserClaimsProcessor());
            }

            if (controllerType == typeof(SubscribeToPortfolioController))
            {
                return new SubscribeToPortfolioController(
                    subscriptionManager,
                    portfolioReader,
                    ClaimsCheckerSingleton.Instance, new PortfolioUserClaimsProcessor());
            }

            if (controllerType == typeof(PortfolioExportController))
            {
                return
                    new PortfolioExportController(
                        new PortfolioExportManagement(
                            portfolioReader,
                            AccountsRepository.GetAccountsRepository(clientPlatform)), new PortfolioUserClaimsProcessor());
            }

            if (controllerType == typeof(PortfolioSecuritiesExportController))
            {
                var portfolioUpdateHandler =
             new CustomPortfolioUpdateHandler(
                 new RepositoryCollection<Portfolio>(clientPlatform),
                 new RepositoryCollection<PortfolioDetails>(clientPlatform),
                 new RepositoryCollection<PortfolioMatches>(clientPlatform),
                 new RepositoryCollection<PortfolioUserInput>(clientPlatform),
                 serviceBusParams);
                var portfolioScreeningTollFilteManagement =
           new ScreeningToolFilterManager(new RepositoryCollection<Filter>(clientPlatform));
                portfolioUpdateHandler.SetScreeningToolFilterManagement(portfolioScreeningTollFilteManagement);
                portfolioUpdateHandler.SetSubscriptionManager(subscriptionManager);
                portfolioUpdateHandler.SetPortfolioMatching(new PortfolioMatching(CompanySearchLogic.GetInstance(), new CorporateDataUniversesLoader(MongoDB.Extensions.MongoFactory.GetCollectionFromDatabase<CorporateData>(connectionStringsManager.GetConnectionString(ConnectionStringType.ClientDW)))));
                var portfolioSecurityManager = new PortfolioSecuritiesImportManagement(
                esgInputFileRepository,
                new RepositoryCollection<Portfolio>(clientPlatform),
               portfolioUpdateHandler,
               new PortfolioWorksheetValidator());

                return new PortfolioSecuritiesExportController(
                    portfolioSecurityManager);
            }

            if (controllerType == typeof(PortfolioSecuritiesUploadController))
            {
                var portfolioUpdateHandler =
             new CustomPortfolioUpdateHandler(
                 new RepositoryCollection<Portfolio>(clientPlatform),
                 new RepositoryCollection<PortfolioDetails>(clientPlatform),
                 new RepositoryCollection<PortfolioMatches>(clientPlatform),
                 new RepositoryCollection<PortfolioUserInput>(clientPlatform),
                 serviceBusParams);
                var portfolioScreeningTollFilteManagement =
           new ScreeningToolFilterManager(new RepositoryCollection<Filter>(clientPlatform));
                portfolioUpdateHandler.SetScreeningToolFilterManagement(portfolioScreeningTollFilteManagement);
                portfolioUpdateHandler.SetSubscriptionManager(subscriptionManager);
                portfolioUpdateHandler.SetPortfolioMatching(new PortfolioMatching(CompanySearchLogic.GetInstance(), new CorporateDataUniversesLoader(MongoDB.Extensions.MongoFactory.GetCollectionFromDatabase<CorporateData>(connectionStringsManager.GetConnectionString(ConnectionStringType.ClientDW)))));
                var portfolioSecurityManager = new PortfolioSecuritiesImportManagement(
                esgInputFileRepository,
                new RepositoryCollection<Portfolio>(clientPlatform),
               portfolioUpdateHandler,
               new PortfolioWorksheetValidator());
                return new PortfolioSecuritiesUploadController(
                    portfolioSecurityManager, new PortfolioUserClaimsProcessor());
            }

            return null;
        }
    }


    
}
